package com.member.mp.web;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.hankcs.hanlp.HanLP;
import com.hankcs.hanlp.seg.common.Term;
import com.member.common.core.domain.R;
import com.member.common.core.page.PageDomain;
import com.member.common.core.page.PageResult;
import com.member.common.core.page.TableDataInfo;
import com.member.common.core.page.TableSupport;
import com.member.common.enums.DeleteEnum;
import com.member.common.enums.EnableStatusEnum;
import com.member.common.enums.OrderDeleteEnum;
import com.member.common.utils.StringUtils;
import com.member.mp.web.user.SupperController;
import com.member.shop.domain.*;
import com.member.shop.dto.GoodsQueryDto;
import com.member.shop.dto.RecommendGoodsQueryDto;
import com.member.shop.service.*;
import com.member.shop.vo.CategoryVo;
import com.member.shop.vo.GoodsDetailVo;
import com.member.shop.vo.GoodsIndexVo;
import com.member.shop.vo.MarketPageVo;
import io.swagger.annotations.Api;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.member.common.enums.DeleteEnum.NOT_DELETE;

/**
 * 【商品】控制器
 *
 * @author wangxin
 * @version 1.0
 * @date Mon Jul 03 22:06:51 CST 2024
 **/
@RestController
@Api(value = "商品接口", tags = {"商品接口"})
@RequestMapping("/wx/goods")
public class GoodsController extends SupperController {

    @Resource
    private ISysBizShopCategoryService sysBizShopCategoryService;
    @Resource
    private ISysBizOftenBuyService oftenBuyService;
    @Resource
    private ISysBizGoodsService sysBizGoodsService;
    @Resource
    private ISysBizGoodsBrowseLogService browseLogService;
    @Resource
    private ISysBizGoodsBrowseService goodsBrowseService;
    @Resource
    private ISysBizRecommendCategoryService recommendCategoryService;
    @Resource
    private ISysBizRecommendGoodsService recommendGoodsService;
    @Resource
    private ISysBizMarketPageService sysBizMarketPageService;
    @Resource
    private ISysBizUserService sysBizUserService;
    @Resource
    private ISysBizGoodsSkuService skuService;

    /**
     * 查询商品分类
     * （查一级分类不用传id）
     *
     * @param id 父分类id（查二级分类时传）
     * @return 一级分类列表
     */
    @GetMapping("/queryFirstCategory")
    public R<List<CategoryVo>> queryFirstCategory(@RequestParam(name = "id", required = false) Long id) {
        Long tenantId = getTenantId();
        List<CategoryVo> sysBizShopCategoryList = sysBizShopCategoryService.queryFirstCategory(id, tenantId);
        return R.ok(sysBizShopCategoryList);
    }

    /**
     * 获取商品详情
     *
     * @param id 商品id
     * @return 商品详情
     */
    @GetMapping("/queryGoodsDetail/{id}")
    public R<GoodsDetailVo> queryGoodsDetail(@PathVariable Long id) {

        SysBizGoods byId = sysBizGoodsService.getById(id);
        if (byId == null || Objects.equals(byId.getDeleted(), OrderDeleteEnum.DELETE.getKey()) || byId.getGrounding() == 1L) {
            return R.not("该商品已下架！");
        }
        Long userId = null;
        Long tenantId = null;
        SysBizUser loginUser = getLoginUser();

        if (loginUser != null) {
            userId = loginUser.getId();
            tenantId = loginUser.getTenantId();
        }

        if (tenantId == null) {
            tenantId = getTenantId();
        }
        GoodsDetailVo goodsDetailVo = sysBizGoodsService.queryGoodsDetail(id, userId, tenantId);
        if (loginUser != null) {
            // 添加到浏览记录
            LambdaQueryWrapper<SysBizGoodsBrowse> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysBizGoodsBrowse::getGoodsId, id);
            queryWrapper.eq(SysBizGoodsBrowse::getUserId, userId);
            queryWrapper.eq(SysBizGoodsBrowse::getTenantId, tenantId);
            List<SysBizGoodsBrowse> list = goodsBrowseService.list(queryWrapper);

            if (!CollectionUtils.isEmpty(list)) {
                SysBizGoodsBrowse sysBizGoodsBrowse = list.get(0);
                LambdaUpdateWrapper<SysBizGoodsBrowse> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.set(SysBizGoodsBrowse::getLastBrowseTime, LocalDateTime.now());
                updateWrapper.set(SysBizGoodsBrowse::getUpdateTime, new Date());
                updateWrapper.eq(SysBizGoodsBrowse::getId, sysBizGoodsBrowse.getId());
                goodsBrowseService.update(updateWrapper);
            } else {
                SysBizGoodsBrowse browse = new SysBizGoodsBrowse();
                browse.setUserId(userId);
                browse.setUpdateTime(new Date());
                browse.setBrowseCount(1L);
                browse.setTenantId(tenantId);
                browse.setStatEndTime(LocalDate.now());
                browse.setStatEndTime(LocalDate.now());
                browse.setStatType(1);
                browse.setLastBrowseTime(LocalDateTime.now());
                browse.setGoodsId(byId.getId());
                browse.setCreateTime(new Date());
                goodsBrowseService.saveOrUpdate(browse);
            }

            SysBizGoodsBrowseLog sysBizGoodBrowseLog = new SysBizGoodsBrowseLog();
            sysBizGoodBrowseLog.setUserId(userId);
            sysBizGoodBrowseLog.setTenantId(tenantId);
            sysBizGoodBrowseLog.setUpdateTime(new Date());
            sysBizGoodBrowseLog.setBrowseTime(LocalDateTime.now());
            sysBizGoodBrowseLog.setGoodsId(byId.getId());
            sysBizGoodBrowseLog.setCreateTime(new Date());
            browseLogService.insertSysBizGoodsBrowseLog(sysBizGoodBrowseLog);
        }

        LambdaQueryWrapper<SysBizOftenBuy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysBizOftenBuy::getDeleted, DeleteEnum.NOT_DELETE.getKey());
        queryWrapper.eq(SysBizOftenBuy::getUserId, userId);

        queryWrapper.eq(SysBizOftenBuy::getTenantId, tenantId);
        queryWrapper.orderByDesc(SysBizOftenBuy::getAddTime);
        queryWrapper.last(" limit 100 ");
        List<SysBizOftenBuy> list = oftenBuyService.list(queryWrapper);
        if (!list.isEmpty()) {
            boolean isOftenBuy = false;
            for (SysBizOftenBuy of : list) {
                if (of.getGoodsId().equals(id)) {
                    isOftenBuy = true;
                    break;
                }
            }
            goodsDetailVo.setIsOfterBuy(isOftenBuy);
        }

        // 查询专题信息
        SysBizMarketPage marketPage = sysBizMarketPageService.getOne(new LambdaQueryWrapper<SysBizMarketPage>().eq(SysBizMarketPage::getDisplayed, EnableStatusEnum.ENABLE.getKey()).eq(SysBizMarketPage::getDeleted, NOT_DELETE.getKey()).eq(SysBizMarketPage::getTenantId, tenantId).apply("FIND_IN_SET({0}, category_goods_id) > 0", id));
        if (marketPage != null) {
            MarketPageVo vo = new MarketPageVo();
            vo.setId(marketPage.getId());
            vo.setTitle(marketPage.getTitle());
            goodsDetailVo.setMarketPage(vo);
        }

        return R.ok(goodsDetailVo);
    }

    /**
     * 获取商品浏览记录(不传分页,猜你喜欢接口)
     *
     * @return 商品详情
     */
    @GetMapping("/queryGoodsByBrowse")
    public R<PageResult<GoodsIndexVo>> queryGoodsByBrowse(GoodsQueryDto goodsQueryDto) {

        SysBizUser loginUser = getLoginUser();
        Long userId = loginUser.getId();
        Long tenantId = loginUser.getTenantId();
        LambdaQueryWrapper<SysBizGoodsBrowse> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysBizGoodsBrowse::getStatType, 1);
        queryWrapper.eq(SysBizGoodsBrowse::getUserId, userId);
        queryWrapper.eq(SysBizGoodsBrowse::getTenantId, tenantId);
        queryWrapper.orderByDesc(SysBizGoodsBrowse::getBrowseCount);
        queryWrapper.orderByDesc(SysBizGoodsBrowse::getLastBrowseTime);

        queryWrapper.last(" limit 100 ");
        List<SysBizGoodsBrowse> list = goodsBrowseService.list(queryWrapper);

        goodsQueryDto.setTenantId(tenantId);
        List<GoodsIndexVo> goodsIndexVoList = new ArrayList<>();
        List<Long> ids = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            ids = list.stream().map(SysBizGoodsBrowse::getGoodsId).collect(Collectors.toList());
            goodsIndexVoList = sysBizGoodsService.selectSysBizGoodsByIds2(goodsQueryDto, ids, tenantId, userId);

        }

        PageResult<GoodsIndexVo> goodsIndexVoPageResult = new PageResult<>(goodsIndexVoList.size(), goodsIndexVoList);
        return R.ok(goodsIndexVoPageResult);
    }

    /**
     * 获取常买商品(最多前100)
     *
     * @return 商品列表
     */
    @GetMapping("/queryGoodsByOftenBuy")
    public R<PageResult<GoodsIndexVo>> queryGoodsByOftenBuy(GoodsQueryDto goodsQueryDto) {
        SysBizUser loginUser = getLoginUser();
        Long userId = loginUser.getId();
        Long tenantId = loginUser.getTenantId();

        LambdaQueryWrapper<SysBizOftenBuy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysBizOftenBuy::getDeleted, DeleteEnum.NOT_DELETE.getKey());
        queryWrapper.eq(SysBizOftenBuy::getUserId, userId);

        queryWrapper.eq(SysBizOftenBuy::getTenantId, tenantId);
        queryWrapper.orderByDesc(SysBizOftenBuy::getAddTime);
        queryWrapper.last(" limit 100 ");
        List<SysBizOftenBuy> list = oftenBuyService.list(queryWrapper);
        goodsQueryDto.setTenantId(tenantId);

        List<GoodsIndexVo> goodsIndexVoList = new ArrayList<>();
        List<Long> ids = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            ids = list.stream().map(SysBizOftenBuy::getGoodsId).collect(Collectors.toList());
            goodsIndexVoList = sysBizGoodsService.selectSysBizGoodsByIds2(goodsQueryDto, ids, tenantId, userId);
        }

        PageResult<GoodsIndexVo> goodsIndexVoPageResult = new PageResult<>(goodsIndexVoList.size(), goodsIndexVoList);
        return R.ok(goodsIndexVoPageResult);
    }

    /**
     * 搜索商品与相似商品列表(带分页)
     *
     * @param goodsQueryDto 参数
     * @return 商品列表
     */
    @GetMapping("/queryGoods")
    public R<PageResult<GoodsIndexVo>> queryGoods(GoodsQueryDto goodsQueryDto) {

        Long tenantId = getTenantId();
        Long userId = Optional.ofNullable(getUserId()).orElse(0L);
        goodsQueryDto.setTenantId(tenantId);
        LambdaQueryWrapper<SysBizShopCategory> sysBizShopCategoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysBizShopCategoryLambdaQueryWrapper.eq(SysBizShopCategory::getDisplayed, 1);
        sysBizShopCategoryLambdaQueryWrapper.eq(SysBizShopCategory::getTenantId, tenantId);
        List<SysBizShopCategory> list = sysBizShopCategoryService.list(sysBizShopCategoryLambdaQueryWrapper);
        List<Long> ids = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            ids = list.stream().map(SysBizShopCategory::getId).collect(Collectors.toList());
        }
        return getGoodsResult(goodsQueryDto, ids, userId, tenantId);
    }

    private R<PageResult<GoodsIndexVo>> getGoodsResult(GoodsQueryDto goodsQueryDto, List<Long> ids, Long userId, Long tenantId) {
        HashMap<String, String> wordMap = new HashMap<>();
        String searchValue = goodsQueryDto.getSearchValue();

        SysBizUser loginUser = sysBizUserService.getById(userId == null ? 0L : userId);
        List<Long> goodIds = new ArrayList<>();
        startPage();
        if (StringUtils.isNotEmpty(searchValue)) {
            List<Term> segment = HanLP.segment(searchValue);

            for (Term term : segment) {
                String word = term.word;
                // 过滤掉长度为一个字的关键词
                if (StringUtils.isNotEmpty(word) && word.length() > 1) {
                    wordMap.put(word, word);
                }
            }
        }

        List<SysBizGoods> sysBizGoodsList = sysBizGoodsService.getGoodsList(goodsQueryDto, wordMap);
        if (!CollectionUtils.isEmpty(sysBizGoodsList)) {
            goodIds = sysBizGoodsList.stream().map(SysBizGoods::getId).collect(Collectors.toList());
        }

        LambdaQueryWrapper<SysBizGoodsSku> queryWrapper = new LambdaQueryWrapper<>();
        if (!CollectionUtils.isEmpty(ids)) {
            queryWrapper.in(SysBizGoodsSku::getGoodsId, goodIds);
        }

        queryWrapper.eq(SysBizGoodsSku::getTenantId, tenantId);
        queryWrapper.eq(SysBizGoodsSku::getStatus, DeleteEnum.NOT_DELETE.getKey());

        List<SysBizGoodsSku> skuList = skuService.list(queryWrapper);
        Map<Long, SysBizGoodsSku> skuInfoMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(skuList)) {
            skuList = skuList.stream().collect(Collectors.groupingBy(SysBizGoodsSku::getGoodsId, Collectors.collectingAndThen(Collectors.minBy(Comparator.comparing(SysBizGoodsSku::getVip1Price)), Optional::get))).values().stream().collect(Collectors.toList());

            // 新增商品信息映射表
            skuInfoMap = skuList.stream().collect(Collectors.toMap(SysBizGoodsSku::getGoodsId, sku -> sku));
        }

        // 预先生成商品ID到最低VIP价格的映射
        Map<Long, BigDecimal> priceMap = new HashMap<>();
        if (loginUser != null) {
            final int grade = loginUser.getMemberGradeId().intValue();
            priceMap = skuList.stream().collect(Collectors.groupingBy(SysBizGoodsSku::getGoodsId, Collectors.collectingAndThen(Collectors.minBy(Comparator.comparing(s -> {
                // 新增活动价格优先逻辑
                if (s.getTag() != null) {
                    return s.getActivityPrice();
                }
                switch (grade) {
                    case 1:
                        return s.getVip1Price();
                    case 2:
                        return s.getVip2Price();
                    case 3:
                        return s.getVip3Price();
                    case 4:
                        return s.getVip4Price();
                    case 5:
                        return s.getVip5Price();
                    default:
                        return BigDecimal.ZERO;
                }
            })), opt -> opt.map(s -> {
                if (s.getTag() != null) {
                    return s.getActivityPrice();
                }
                switch (grade) {
                    case 1:
                        return s.getVip1Price();
                    case 2:
                        return s.getVip2Price();
                    case 3:
                        return s.getVip3Price();
                    case 4:
                        return s.getVip4Price();
                    case 5:
                        return s.getVip5Price();
                    default:
                        return BigDecimal.ZERO;
                }
            }).orElse(BigDecimal.ZERO))));
        }

        TableDataInfo dataTable = getDataTable(sysBizGoodsList);
        List<?> rows = dataTable.getRows();
        List<GoodsIndexVo> item = new ArrayList<>();
        for (Object row : rows) {
            SysBizGoods goodsIndexVo = (SysBizGoods) row;
            GoodsIndexVo target = new GoodsIndexVo();
            BeanUtils.copyProperties(goodsIndexVo, target);
            // 从预生成的映射表获取价格
            if (loginUser != null) {
                target.setMinSalesPrice(priceMap.getOrDefault(goodsIndexVo.getId(), BigDecimal.ZERO));
                target.setMaxSalesPrice(priceMap.getOrDefault(goodsIndexVo.getId(), BigDecimal.ZERO));
            }
            // 新增商品名称和单位赋值
            SysBizGoodsSku skuInfo = skuInfoMap.get(goodsIndexVo.getId());
            if (skuInfo != null) {
                target.setName(skuInfo.getSkuName());
                target.setUnit(skuInfo.getLongUnit());
            }
            item.add(target);
        }


        sysBizGoodsService.setOperationTag(goodsQueryDto, item);

        PageResult<GoodsIndexVo> goodsIndexVoPageResult = new PageResult<>(dataTable.getTotal(), item);
        return R.ok(goodsIndexVoPageResult);
    }


    /**
     * 获取推荐商品
     *
     * @param recommendGoodsQueryDto 参数
     * @return 商品列表
     */
    @GetMapping("/queryGoodsByRecommend")
    public R<PageResult<GoodsIndexVo>> queryGoodsByRecommend(RecommendGoodsQueryDto recommendGoodsQueryDto) {
        LambdaQueryWrapper<SysBizRecommendCategory> recommendWrapper = new LambdaQueryWrapper<>();

        Long tenantId = getTenantId();
        Long userId = Optional.ofNullable(getUserId()).orElse(0L);
        recommendWrapper.eq(SysBizRecommendCategory::getTenantId, tenantId);
        recommendWrapper.eq(recommendGoodsQueryDto.getRecommendCategoryId() != null, SysBizRecommendCategory::getId, recommendGoodsQueryDto.getRecommendCategoryId());
        recommendWrapper.eq(SysBizRecommendCategory::getDeleted, DeleteEnum.NOT_DELETE.getKey());
        List<SysBizRecommendCategory> list = recommendCategoryService.list(recommendWrapper);
        List<Long> ids = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            ids = list.stream().map(SysBizRecommendCategory::getId).collect(Collectors.toList());
        }

        LambdaQueryWrapper<SysBizRecommendGoods> recommendGoodsWrapper = new LambdaQueryWrapper<>();
        if (!CollectionUtils.isEmpty(ids)) {
            recommendGoodsWrapper.in(SysBizRecommendGoods::getRecommendCategoryId, ids);
        }
        recommendGoodsWrapper.eq(SysBizRecommendGoods::getDeleted, DeleteEnum.NOT_DELETE.getKey());
        recommendGoodsWrapper.eq(SysBizRecommendGoods::getTenantId, tenantId);
        recommendGoodsWrapper.orderByDesc(SysBizRecommendGoods::getOrderNum);
        recommendGoodsWrapper.last(" limit 100 ");
        List<SysBizRecommendGoods> recommendGoodsList = recommendGoodsService.list(recommendGoodsWrapper);
        //
        GoodsQueryDto goodsQueryDto = new GoodsQueryDto();

        BeanUtils.copyProperties(recommendGoodsQueryDto, goodsQueryDto);
        goodsQueryDto.setTenantId(tenantId);

        List<GoodsIndexVo> goodsIndexVoList = new ArrayList<>();
        ids = new ArrayList<>();

        if (!CollectionUtils.isEmpty(recommendGoodsList)) {
            ids = recommendGoodsList.stream().map(SysBizRecommendGoods::getGoodsId).distinct().collect(Collectors.toList());

            LambdaQueryWrapper<SysBizGoodsSku> queryWrapper = new LambdaQueryWrapper<>();
            if (!CollectionUtils.isEmpty(ids)) {
                queryWrapper.in(SysBizGoodsSku::getId, ids);
            }

            queryWrapper.eq(SysBizGoodsSku::getTenantId, tenantId);
            queryWrapper.eq(SysBizGoodsSku::getStatus,OrderDeleteEnum.NOT_DELETE.getKey());

            List<SysBizGoodsSku> skuList = skuService.list(queryWrapper);
            if (!CollectionUtils.isEmpty(skuList)) {
                goodsIndexVoList = sysBizGoodsService.selectSysBizGoodsBySkuId(goodsQueryDto, skuList, userId);
            }
        }
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        // 起始位置
        int start = pageNum <= 0 ? 0 : (pageNum > pageSize ? (pageSize - 1) * pageSize : (pageNum - 1) * pageSize);
        // 终止位置
        int end = pageNum <= 0 ? (Math.min(pageSize, goodsIndexVoList.size())) : (Math.min(pageSize * pageNum, goodsIndexVoList.size()));

        List<GoodsIndexVo> goodsIndexVos = new ArrayList<>();
        if (CollectionUtils.isEmpty(goodsIndexVoList)) {
            goodsIndexVos = Collections.emptyList();
        } else {
            goodsIndexVos = goodsIndexVoList.subList(start, end);
        }

        PageResult<GoodsIndexVo> goodsIndexVoPageResult = new PageResult<>(goodsIndexVoList.size(), goodsIndexVos);
        return R.ok(goodsIndexVoPageResult);
    }


}
